[#ftl strict_vars=true]

[#-- In principle, you could replace html32.ftl
     with another library to customize the HTML output --]
[#import "html32.ftl" as html]
[#escape x as (x)?html]
[@html.page]

[@html.nonterminals]
 [#list grammar.BNFProductions as production]
  [#var classname=production.class.name?split(".")?last]
  [@html.production production]
     [#if classname = "JavaCodeProduction"]
       [@html.javacode production/]
     [#else]
       [@expansion production.expansion/]
     [/#if]
  [/@]
 [/#list]
[/@]
<HR>
[@html.tokenProductions]
[#list grammar.allTokenProductions as tp]
 [#if tp.explicit]
   [@tokenProduction tp/]
 [/#if]
[/#list]
[/@]

[/@]

[#macro expansion exp]
   [#var classname=exp.class.name?split(".")?last]
     [#if classname = "Action" || classname = "Lookahead"]
        [#--Do nothing--]
     [#elseif classname = "Choice"]
       [#list exp.choices as choice]
          [@expansion choice/][#t]
             [#if choice_has_next]
               |[#t]
             [/#if]
       [/#list]
     [#elseif classname = "NonTerminal"]
       [@html.nonTerminal exp/]
     [#elseif classname = "Sequence"]
        [#list exp.units as unit]
           [#var needsParen=unit.class.name?ends_with("Sequence") || unit.class.name?ends_with("Choice")]
           [#if needsParen]([#t][/#if]
             [@expansion unit/] [#t]
           [#if needsParen])[#t][/#if] 
        [/#list]
     [#elseif classname = "TryBlock"]
       [#if exp.nestedExpansion.class.name?ends_with("Choice")]
        ([@expansion exp.nestedExpansion/])
       [#else]
        [@expansion exp.nestedExpansion/]
       [/#if]
     [#elseif classname = "OneOrMore"]
       ([@expansion exp.nestedExpansion/])+
     [#elseif classname = "ZeroOrMore"]
       ([@expansion exp.nestedExpansion/])*
     [#elseif classname = "ZeroOrOne"]
       ([@expansion exp.nestedExpansion/])?
     [#else]
       [#-- must be a regexp --]
       ${exp.emit()}
     [/#if]
[/#macro]

[#macro tokenProduction tp]
 [@html.tokenProduction]
  &lt;[#t]
  [#list tp.lexStates as lexState]
     ${lexState}[#if lexState_has_next], [/#if][#t]
  [/#list]
  &gt;[#t]
  [#lt] ${tp.kind}[#if tp.ignoreCase][IGNORE_CASE][/#if] : { 
  [#list tp.regexpSpecs as respec]
    [#var re=respec.regexp]
    [#if !re.private]
       ${re.emit()}[#if re.nextState??] : ${re.nextState}[/#if][#lt]
       [#if respec_has_next]|[/#if][#t]
    [/#if]
  [/#list]
}

 [/@]
[/#macro]
[/#escape]